package com.shqcjd.sinopecdemomobile.ui.activity.remote;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.KeyEvent;
import android.view.SurfaceView;
import android.view.View;
import android.widget.CheckBox;
import android.widget.Chronometer;
import android.widget.CompoundButton;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.afollestad.materialdialogs.DialogAction;
import com.afollestad.materialdialogs.MaterialDialog;
import com.google.gson.Gson;
import com.orhanobut.logger.Logger;
import com.shqcjd.sinopecdemomobile.R;
import com.shqcjd.sinopecdemomobile.api.ApiService;
import com.shqcjd.sinopecdemomobile.app.MyApp;
import com.shqcjd.sinopecdemomobile.helper.rxjavahelper.RxObserver;
import com.shqcjd.sinopecdemomobile.helper.rxjavahelper.RxSchedulersHelper;
import com.shqcjd.sinopecdemomobile.model.ResponseData;
import com.shqcjd.sinopecdemomobile.model.eventbus.ReloginEvent;
import com.shqcjd.sinopecdemomobile.model.pojo.ChannelUser;
import com.shqcjd.sinopecdemomobile.model.pojo.SignalingMsgBean;
import com.shqcjd.sinopecdemomobile.ui.adapter.RemoteUserListAdapter;
import com.shqcjd.sinopecdemomobile.ui.base.BaseActivity;
import com.shqcjd.sinopecdemomobile.ui.base.BasePresenter;
import com.shqcjd.sinopecdemomobile.util.PrefUtils;
import com.shqcjd.sinopecdemomobile.util.SpacesItemDecoration;
import com.shqcjd.sinopecdemomobile.util.ToastUtils;
import com.shqcjd.sinopecdemomobile.util.UIUtils;
import com.shqcjd.sinopecdemomobile.widget.BadgeHelper;
import com.tbruyelle.rxpermissions2.RxPermissions;

import org.greenrobot.eventbus.EventBus;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import butterknife.BindView;
import butterknife.OnClick;
import io.agora.AgoraAPI;
import io.agora.AgoraAPIOnlySignal;
import io.agora.IAgoraAPI;
import io.agora.rtc.Constants;
import io.agora.rtc.RtcEngine;
import io.agora.rtc.video.VideoCanvas;
import io.agora.rtc.video.VideoEncoderConfiguration;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;

/**
 * 推送视频端
 */
public class PushVideoCallActivity extends BaseActivity implements MyApp.OnAgoraEngineInterface {
    @BindView(R.id.remote_video_view_container)
    FrameLayout container;
    @BindView(R.id.cb_call_mute_button)
    CheckBox cbCallMuteButton;
    @BindView(R.id.ll_mute_btn)
    LinearLayout llMuteBtn;
    @BindView(R.id.ll_file_btn)
    LinearLayout llFileBtn;
    @BindView(R.id.chronometer_layout)
    Chronometer chronometer_layout;
    @BindView(R.id.ll_hang_up_btn)
    LinearLayout llHangUpBtn;
    @BindView(R.id.rl_menu)
    RelativeLayout rlMenu;
    @BindView(R.id.rl_full_screen)
    RelativeLayout rlFullScreen;
    @BindView(R.id.rv_user_list)
    RecyclerView rv_user_list;
    @BindView(R.id.tv_msg_content)
    TextView tv_msg_content;
    private Context mContext;
    private AgoraAPIOnlySignal mAgoraAPI;
    private RtcEngine mRtcEngine;
    private String channelID;
    private int userID;
    List<ChannelUser> channelUserList = new ArrayList<>();

    private boolean timerFlag = true;

    private final int TIME = 1000;
    private int timingNum = 20;
    private Handler finishHandler = new Handler();
    private Runnable finishRunnable = new Runnable() {
        @Override
        public void run() {
            Logger.i("计时:" + timingNum);
            if (timingNum == 1) {
                ToastUtils.showShort(mContext, "网络信号不稳定,无法进行远程指导");
                finishHandler.removeCallbacks(finishRunnable);
                new Handler().postDelayed(new Runnable() {
                    public void run() {
                        finish();
                    }
                }, 2000);
            } else {
                timingNum--;
                finishHandler.postDelayed(finishRunnable, TIME);
            }
        }
    };
    private BadgeHelper badgeHelper;
    private int unReadMsgNum = 0;//未读消息数量
    private boolean isHasFile = false;//是否有发送文件，用于判断进入文件列表
    private String kks;
    private String problemFeedbackId;
    private String taskCode;
    private String remoteId;
    private RemoteUserListAdapter remoteUserListAdapter;
    private String taskId;

    @Override
    protected BasePresenter createPresenter() {
        return null;
    }

    @Override
    protected int provideContentViewId() {
        return R.layout.activity_push_video_call;
    }

    @Override
    public void initView() {
        mContext = this;

        channelID = getIntent().getStringExtra("channelID");
        remoteId = getIntent().getStringExtra("remoteId");
        kks = getIntent().getStringExtra("kks");
        problemFeedbackId = getIntent().getStringExtra("problemFeedbackId");
        taskCode = getIntent().getStringExtra("taskCode");
        taskId = getIntent().getStringExtra("taskId");

        userID = PrefUtils.getInt(mContext, PrefUtils.USER_ID, -1);

        cbCallMuteButton.setOnCheckedChangeListener(oncheckChangeListerener);

        //消息红点
        badgeHelper = new BadgeHelper(this)
                .setBadgeType(BadgeHelper.Type.TYPE_TEXT)
                .setBadgeOverlap(true, false);
        badgeHelper.bindToTargetView(llFileBtn);
        badgeHelper.setVisibility(View.GONE);

        remoteUserListAdapter = new RemoteUserListAdapter();
        rv_user_list.setLayoutManager(new LinearLayoutManager(this));
        int leftRight = UIUtils.dip2px(0);
        int topBottom = UIUtils.dip2px(10);
        rv_user_list.addItemDecoration(new SpacesItemDecoration(leftRight, topBottom));
        rv_user_list.setAdapter(remoteUserListAdapter);


        checkPermissions();

    }

    /**
     * 控制静音
     */
    private CompoundButton.OnCheckedChangeListener oncheckChangeListerener = new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            mRtcEngine.muteLocalAudioStream(isChecked);
        }
    };

    /**
     * 检测权限
     */
    private void checkPermissions() {
        RxPermissions permissions = new RxPermissions(this);
        permissions.setLogging(true);
        permissions.request(Manifest.permission.RECORD_AUDIO,
                Manifest.permission.CAMERA,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)
                .subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean aBoolean) throws Exception {
                        if (aBoolean) {
                            initAgoraEngineAndJoinChannel();
                        } else {
                            ToastUtils.showShort(mContext, "缺少远程指导必要权限");
                            finish();
                        }
                    }
                });
    }

    /**
     * 初始化远程指导
     */
    private void initAgoraEngineAndJoinChannel() {
        //初始化视频
        initializeAgoraEngine();     // 步骤1
        setupVideoProfile();         // 步骤2
        MyApp.the().setOnAgoraEngineInterface(this);
        setupLocalVideo();          // 步骤3
        joinChannel();               // 步骤4

        finishHandler.postDelayed(finishRunnable, TIME);

    }

    private void initializeAgoraEngine() {
        mAgoraAPI = MyApp.the().getmAgoraAPI();
        mRtcEngine = MyApp.the().getmRtcEngine();
        if (mRtcEngine != null) {
            mRtcEngine.setLogFile("/sdcard/sdklog.txt");
        }
    }

    private void setupVideoProfile() {
        mRtcEngine.enableVideo();

        VideoEncoderConfiguration.VideoDimensions vd_1280x720 = VideoEncoderConfiguration.VD_1280x720;
        VideoEncoderConfiguration.FRAME_RATE frameRateFps15 = VideoEncoderConfiguration.FRAME_RATE.FRAME_RATE_FPS_15;
        int standardBitrate = VideoEncoderConfiguration.STANDARD_BITRATE;
        VideoEncoderConfiguration.ORIENTATION_MODE orientationModeAdaptive = VideoEncoderConfiguration.ORIENTATION_MODE.ORIENTATION_MODE_FIXED_LANDSCAPE;
        VideoEncoderConfiguration videoEncoderConfiguration = new VideoEncoderConfiguration(vd_1280x720, frameRateFps15, standardBitrate, orientationModeAdaptive);
        mRtcEngine.setVideoEncoderConfiguration(videoEncoderConfiguration);
    }

    private void setupLocalVideo() {
//        SurfaceView surfaceView = RtcEngine.CreateRendererView(getBaseContext());
////        surfaceView.setZOrderMediaOverlay(true);
//        container.addView(surfaceView);
//        //设置本地视频视频
//        mRtcEngine.setupLocalVideo(new VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_HIDDEN, 0));
////        //镜像问题调用
////        mRtcEngine.setParameters("{\"che.video.localViewMirrorSetting\":\"disableMirror\"}");
//        mRtcEngine.startPreview();

        SurfaceView surfaceView = RtcEngine.CreateRendererView(getBaseContext());
        container.addView(surfaceView);
        mRtcEngine.setupLocalVideo(new VideoCanvas(surfaceView, VideoCanvas.RENDER_MODE_HIDDEN, 0));
        container.setVisibility(View.VISIBLE);
        mRtcEngine.startPreview();
        //转换摄像头
        mRtcEngine.switchCamera();
    }

    private void joinChannel() {
        mRtcEngine.setChannelProfile(1);
        mRtcEngine.setClientRole(Constants.CLIENT_ROLE_BROADCASTER);
        mRtcEngine.enableWebSdkInteroperability(true);
        //关闭使用本地摄像头设备
//        mRtcEngine.enableLocalVideo(false);
        //加入信令频道
        mAgoraAPI.channelJoin(channelID);
        //加入视频频道
        Logger.i("加入房间号:" + channelID);
        int i1 = mRtcEngine.leaveChannel();
        int i = mRtcEngine.joinChannel(null, channelID, "Extra Optional Data", userID);// if you do not specify the uid, we will generate the uid for you
        Logger.i("加入频道码:" + i + "  离开频道:" + i1);
    }


    @Override
    protected void onResume() {
        super.onResume();
        addSignalingCallback();
    }

    private void addSignalingCallback() {
        if (mAgoraAPI == null) {
            return;
        }

        mAgoraAPI.callbackSet(new AgoraAPI.CallBack() {

            /**
             * 收到频道消息回调
             * @param channelID 频道名
             * @param account 客户端定义的用户账号
             * @param uid 固定填 0
             * @param msg 消息正文
             */
            @Override
            public void onMessageChannelReceive(String channelID, final String account, final int uid, final String msg) {
                super.onMessageChannelReceive(channelID, account, uid, msg);
                Logger.i("接收到频道消息: account:" + account + " uid:" + uid + " msg:" + msg);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        SignalingMsgBean signalingMsgBean = new Gson().fromJson(msg, SignalingMsgBean.class);
                        ToastUtils.showShort(mContext, "收到新消息");
                        if (signalingMsgBean.msgType == 1) {// 1：消息  2：文件
                            tv_msg_content.setText("" + signalingMsgBean.content);
                        } else if ((signalingMsgBean.msgType == 2)) {
                            unReadMsgNum++;
                            isHasFile = true;
                            if (badgeHelper.getVisibility() == View.GONE) {
                                badgeHelper.setVisibility(View.VISIBLE);
                            }
                            badgeHelper.setBadgeNumber(unReadMsgNum);//数字
                        }

                    }
                });
            }

            @Override
            public void onLogout(final int i) {
                Logger.i("Agora onLogout:" + i);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (i == IAgoraAPI.ECODE_LOGOUT_E_KICKED) { // 账号其他地方登录
                            EventBus.getDefault().post(new ReloginEvent());
                        } else if (i == IAgoraAPI.ECODE_LOGOUT_E_NET) { // 网络问题
                            ToastUtils.showShort(mContext, "网络异常，可能无法收到对方文件！");
                        }
                    }
                });

            }

        });
    }

    @OnClick({R.id.ll_mute_btn, R.id.ll_file_btn, R.id.ll_hang_up_btn, R.id.rl_full_screen})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.ll_mute_btn://静音
                cbCallMuteButton.setChecked(!cbCallMuteButton.isChecked());
                break;
            case R.id.ll_file_btn://打开文件列表
                if (isHasFile) {
                    Intent intent = new Intent(PushVideoCallActivity.this, RemoteFileListActivity.class);
                    intent.putExtra("channelID", channelID);
                    startActivity(intent);
                    unReadMsgNum = 0;
                    badgeHelper.setVisibility(View.GONE);
                } else {
                    ToastUtils.showShort(mContext, "暂无指导文件!");
                }


                break;
            case R.id.ll_hang_up_btn://挂断
                callOutHangup();
                break;
            case R.id.rl_full_screen://显示隐藏菜单
                rlMenu.setVisibility(rlMenu.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
                break;
        }
    }

    private void callOutHangup() {
        new MaterialDialog.Builder(mContext)
                .title("远程指导中，是否结束？")
                .positiveText("确认")
                .negativeText("取消")
                .onAny(new MaterialDialog.SingleButtonCallback() {
                    @Override
                    public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
                        if (which == DialogAction.POSITIVE) {//确认
//                            guideHandle("1");
                            finish();


                        } else if (which == DialogAction.NEGATIVE) {//取消
                            dialog.dismiss();
                        }

                    }
                }).show();
    }


    //对方离开
    private void onRemoteUserOffline(int uid) {
        Logger.i("远程指导:离开:" + uid);
        for (int i = 0; i < channelUserList.size(); i++) {
            if (channelUserList.get(i).userId == uid) {
                channelUserList.remove(i);
                break;
            }

        }
        remoteUserListAdapter.setNewData(channelUserList);
//        guideHandle("1");
        if (remoteId.equals(uid + "")) {
            //对方离开
            showEvaluation();
        }

    }

    private void showEvaluation() {
        MaterialDialog dialog = new MaterialDialog.Builder(this)
                .customView(R.layout.custome_guide_evaluation, false)
                .show();
        View customView = dialog.getCustomView();
        customView.findViewById(R.id.tv_positive).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
                setLike();

            }
        });
        customView.findViewById(R.id.tv_cancel).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                dialog.dismiss();
                finish();
            }
        });
    }

    private void setLike() {
        ApiService.guideLike(channelID)
                .compose(RxSchedulersHelper.io_main())
                .subscribe(new RxObserver<ResponseData>() {
                    @Override
                    public void _onSubscribe(Disposable d) {
                        super._onSubscribe(d);
                        showWaitingDialog("点赞中...");
                    }

                    @Override
                    public void _onNext(ResponseData retData) {
                    }

                    @Override
                    public void _onError(String errorMessage) {
                        hideWaitingDialog();
                        ToastUtils.showShort(mContext, errorMessage);
                        finish();
                    }

                    @Override
                    public void _onComplete() {
                        super._onComplete();
                        hideWaitingDialog();
                        finish();
                    }
                });
    }


    //已完成远端视频首帧解码回调。
    @Override
    public void onFirstRemoteVideoDecoded(int uid, int width, int height, int elapsed) {

    }

    //远端用户加入当前频道回调。
    @Override
    public void onUserJoined(int uid, int elapsed) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Logger.i("远程指导:加入:" + uid);
                if (timerFlag) {
                    timerFlag = false;
                    createGuide();//调用后台创建远程指导接口
                }
                //每当人加入查询频道信息
                queryUser(uid + "");

            }
        });
    }

    private void queryUser(String id) {
        ApiService.queryChannelUser(id)
                .compose(RxSchedulersHelper.io_main())
                .subscribe(new RxObserver<ResponseData<ChannelUser>>() {
                    @Override
                    public void _onNext(ResponseData<ChannelUser> retData) {
                        if (retData.retCode == 10000) {
                            channelUserList.add(retData.data);
                            remoteUserListAdapter.setNewData(channelUserList);
                        }
                    }

                    @Override
                    public void _onError(String errorMessage) {

                    }
                });
    }

    /**
     * 后台创建远程指导接口
     */
    private void createGuide() {
        Map<String, String> map = new HashMap<>();
        map.put("userId", userID + "");
        map.put("managerUserId", remoteId);
        map.put("roomId", channelID);
        map.put("kks", kks);
        map.put("problemFeedbackId", problemFeedbackId);
        map.put("taskCode", taskCode);
        map.put("taskId", taskId);
        ApiService.createGuide(new JSONObject(map))
                .compose(RxSchedulersHelper.io_main())
                .subscribe(new RxObserver<ResponseData>() {
                    @Override
                    public void _onSubscribe(Disposable d) {
                        super._onSubscribe(d);
                        showWaitingDialog("创建远程指导中...");
                    }

                    @Override
                    public void _onNext(ResponseData retData) {
                        if (retData != null && retData.retCode == 10000) {
                            finishHandler.removeCallbacks(finishRunnable);//移除定时关闭
                            chronometer_layout.setBase(SystemClock.elapsedRealtime());//计时器清零
                            chronometer_layout.start();
                            guideHandle("0");
                        } else {
                            ToastUtils.showShort(mContext, retData.retMsg);
                        }


                    }

                    @Override
                    public void _onError(String errorMessage) {
                        ToastUtils.showShort(mContext, errorMessage);
                        hideWaitingDialog();
                    }

                    @Override
                    public void onComplete() {
                        super.onComplete();
                        hideWaitingDialog();
                    }
                });
    }

    /**
     * 录制/结束远程指导
     */
    private void guideHandle(String handle) {
        Map<String, String> map = new HashMap<>();
        map.put("roomId", channelID);
        map.put("operation", handle);//	0:开始录制、1:结束录制
        map.put("guideStatus", "0");//0:专家指导,1:全程录像，operation为(0:开始录制)该参数有效
        ApiService.handleGuide(new JSONObject(map))
                .compose(RxSchedulersHelper.io_main())
                .subscribe(new RxObserver<ResponseData>() {
                    @Override
                    public void _onSubscribe(Disposable d) {
                        super._onSubscribe(d);
                        if (handle.equals("1")) {
                            showWaitingDialog("结束中");
                        } else {
                            showWaitingDialog("开启录制");
                        }

                    }

                    @Override
                    public void _onNext(ResponseData responseData) {
                        if (handle.equals("1")) {
                            finish();
                        }
                        hideWaitingDialog();
                    }

                    @Override
                    public void _onError(String errorMessage) {
                        if (handle.equals("1")) {
                            finish();
                        }
                        hideWaitingDialog();
                    }
                });
    }


    @Override
    public void onUserOffline(int uid, int reason) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                onRemoteUserOffline(uid);
            }
        });
    }

    //远端用户暂停/重新发送视频流回调。
    @Override
    public void onUserMuteVideo(int uid, boolean muted) {

    }

    @Override
    public void onJoinChannelSuccess(String channel, int uid, int elapsed) {

    }

    @Override
    public void onError(int err) {

    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (finishHandler != null) {
            finishHandler.removeCallbacks(finishRunnable);//移除定时关闭
        }

        mAgoraAPI.channelLeave(channelID);
        if (mRtcEngine != null) {
            mRtcEngine.switchCamera();
            mRtcEngine.stopPreview();
            mRtcEngine.leaveChannel();//离开频道
        }
//        mRtcEngine = null;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
}
